CONS: Who says "movie" of a 4 minute video, this guy's vocabulary is mad.
PROS:
Was he good? Yes, he is good THE COURSE IS GOOD.
He does not overwhelm you with jack tons of completely miniscule details of every single feature a language has. The course is "Javascript ESSENTIAL" and the title wasn't a LIE! You genuinely learn the essential concepts so at the end of the course, you finally get things now.
There are mini exercises that proves and test if you genuinely understood what he was saying. Every coding exercises are in the context of what he taught in that specific and a mix of preceding chapters.
He uses ANALOGY and VISUAL representations at time
Remember that the browser renders HTML file from top to bottom
Loading Script ERROR:
<body>
loadappendChild
.A SHIT SOLUTION (explained later why it's shit)
To fix this, I can then take the script tag entirely and paste it in below the body element.
<body>
load Loading JavaScript in the footer, is now an anti pattern.
From here on forward, JavaScript should always be loaded in the head, and then you use async or defer, to control when that JavaScript is executed on the document.
The only difference between the two is when the JS file is executed
HTML parsed
and js downloaded
)“render_blocking.png” could not be found.
Can also be called CONTENT Blocking
So this is the default behavior.
This is called content or render blocking, because it quite literally, blocks the rendering of the content in the page. And it can cause all sorts of weird problems, like what you saw in my example, and it also causes the page to just load slower, and it's not a great solution.
“async.png” could not be found.
The async keyword changes this behavior significantly.
Simultaneously do
HTML Parsing
DOWNLOADING JS FILE
Execute JS FILE only if
JS Downloaded DONE
Also, temporarily PAUSE HTML parsing
Continue HTML Parsing
After JS Execution
This is good for some purposes, especially when you need, to
“defer.png” could not be found.
The defer keyword
Simultaneously do
HTML Parsing
DOWNLOADING JS File
Execute JS File after both are done:
HTML Parsed DONE
JS Downloaded DONE
Or ALL resources have been parsed/downloaded
What happens when you defer
JavaScript?
The browser loads the JavaScript asynchronously when it is encountered, then waits until all HTML is rendered before executing the script.
As you start working with JavaScript,
you'll quickly notice these files tend to get really large and kind of hard to work with.
To solve this problem, we now have something called JavaScript modules.
Now to get this to work in practice, you have to do one more thing.
Inside index.html, you need to tell the browser,
module
, both files automatically get deferred
Javascript - In calling properties in an object. Properties is what we use to describe an object
Two ways
myObject.["property"]
myObject.property
Object is defined with curly braces around it along with its properties or optionally methods
const objectDemo = {
dance: "Mambo",
number: "5",
}
A method is actually just a function inside of an object. A method is a verb
Okay wtf, these are the same thing
class Name {} // Class Declaration
const Name = class{} // Class Expression
Questions:
What does the this keyword refer to in a class?
-> Why is this wrong "this refers to the class constructor."
-> Why is this the correct answer "this refers to the current object created from the class."
// Arrow function with single parameter and single expression
const double = x => x * 2;
// Equivalent traditional function expression
const double = function(x) {
return x * 2;
};
// Arrow function with multiple parameters and block of code
const sum = (a, b) => {
num = a + b
return num;
};
// Equivalent traditional function expression
const sum = function(a, b) {
num = a + b
return a + b;
};
// Arrow function with no parameters
const getCurrentYear = () => new Date().getFullYear();
// Equivalent traditional function expression
const getCurrentYear = function() {
return new Date().getFullYear();
};
NEW BETTER WAY
document.querySelector() // Returns the HTML snippet code
document.querySelectorAll() // Returns a NodeList (A node list containing each element object matching the query.)
Old way of getting element
document.getElementsByClassName() // Receives a string of classnames to be found as its parameter.
document.getElementById()
innerHTML
vs outerHTML
inner basically is what's inside of the element tag
outer includes the element tag, for instance
document.querySelector("ul").innerHTML
// <ul>
tag is EXcludeddocument.querySelector("ul").outerHTML
// ul
tag is INCLUDEDA common task in JavaScript is to modify the classes of an element in some way.
This is a simple way of without having to inject CSS into the HTML itself.
Class manipulation is common enough,
that we have two specialized properties for it.
The first one and the oldest one is className
, and it's
document.querySelector("h1").className = "new-class-name"
// Assigning new valueclassName
holds a string, listing out all the classes appended to an element.className
classList
propertyTo get around both of these problems, use the classList
property.
returns
Dom token collection of all the classes appended to an element.
Methods to manipulate individual classes
classList.add()
classList.remove()
classList.toggle()
toggle, true or falseclassList.replace("old_class", "new_class")
If you want to add, remove, toggle or replace classes you should always use the class list property, and use the methods that come with it.
If on the other hand, you're looking for a string and you want just the output of all the classes to do something else with, you can use the class name property.
Need to pass data from one element to the other?
A node map and not an array
NamedNodeMap {0: src, 1: alt, src: src, alt: alt, length: 2}
0: src
1: alt
alt: alt
src: src
length: 2
[[Prototype]]: NamedNodeMap
Explanation:
One thing worth noting here is the attributes property returns a different type of data
from the class name and class list properties.
What we get is a named node map and it is not an array.
So we can't use array methods on it.
There's a simple reason for this.
An attribute is a more complex piece of data, it has a key and a value and we need to be able to manipulate just the key or just the value or both at any time and a simple array wouldn't do that.
Check, Get, Set/Create and Remove
document.querySelector("img").hasAttribute("src")
// Check if element has attribute
document.querySelector("img").getAttribute("src")
// Get attribute
document.querySelector("img").setAttribute("alt", "value to set")
// Set/Create new attribute
document.querySelector("img").removeAttribute("title")
Need to change the appearance of a specific element for some reason?
Modify, Add, Change, etc.. etc...
document.querySelector("site.title").style
document.querySelector("site.title").style.backgroundColor = "pink"
Template literal creates HTML in Javascript
This is an effective way of injecting new HTML into a document,
but it's also rather crude and destructive.
WHY: It requires an existing element to be in the HTML documents,
and it wipes up whatever code was contained inside that element. And that can be a problem.
We're also replacing all the content inside the main element, so this new text disappears.
Let's create a new element. Uses Document.createElement()
Parameter expects a valid html element (div
, p
)
// Creating Element
const newArticle = document.createElement("article"); // Document.createElement()
newArticle.classList.add("backpack"); // The element is created, but has not been added to the DOM.
newArticle.setAttribute("id", "everyday");
newArticle.innerHTML = content; // content is a variable that has `html code`
// Get the value of newArticle element(which is empty for now),
// then replace it with the variable `content`
We're going to append it now.
ParentNode.append()
// Adding the newly created element to the existing element in the DOM
const main = document.querySelector(".maincontent")
main.append(newElement) // ParentNode.append()
Now we've created the element, we're going to append it now.
Uses ParentNode.append()
The append method can be used to add one or several comma-separated elements and they all go inside but at the end of the parent Node.
And it can also be used to append a string of texts if that's what you want to do.
ParentNode.append()
// Adding the newly created element to the existing element
const main = document.querySelector(".maincontent")
main.append(newElement) // ParentNode.append()
ParentNode.prepend()
Add element to
First child of the parent,
Just places the element at the top instead of at the bottom of the parent element.
ParentNode.appendChild()
Same as .append()
Also returns this element to you.
ParentNode.replaceChild()
Replaces a child element of a parent.
ParentNode.insertBefore(newElement, parentElement)
Allows us to insert an element before the parent elements.
Add element before other elements rather than just inside them
ParentNode.insertAdjacent()
Add element after other elements rather than just inside them
Can specify exactly where you want that new element to appear,
So, the way of seeing variables here is a container of an object. Let's say,
5
(a physical number 5
)And when I say container is created I mean that pretty literally.
So basically, each time we create a variable, we're consuming a space in the ram, then we put whatever data we want inside of that consumed space.
a = b
assigns the value of b to a.
a == b
tests for equality between a and b.
STRICT: a === b
tests for identical equality (checks if same data type) between a and b.
Important New Term:
The term function is typically used to refer to as a function that sits on itself
a method is a function that sits inside an object and acts on that object.
They're effectively the same thing, they just appear in different contexts.
A function can be created in a couple of different ways
and how we create a function
has an impact on how it can be used.
Function declaration is hoisted to the to the top of their containing scope during the compilation phase.
This means you can call a function before it's declared in the code. However, this hoisting behavior applies to the scope in which the function is declared, not necessarily the global scope.
console.log(myFunction());
// ^--- This works, even though myFunction is called before its declaration
function myFunction() {
return "Hello, world!";
}
myFunction()
is called before its declaration in the code.myFunction()
is available to be called from anywhere in the same scope, including before its actual declaration.So just like a VAR,
If you create a new function and use the same name, that new function will take precedence further down in the code.
So you can accidentally override an existing function if you're using function declarations.
function myFunction() {
console.log("First declaration");
}
myFunction(); // Output: "Second Declaration"
function myFunction() {
console.log("Second declaration");
}
// Calling the function
myFunction(); // Output: "Second declaration"
const getRectArea = function (width, height) {
return width * height;
};
So if we're using a const
to store the function expression,
In an IFE, we wrap an
It's immediately invoked and run as soon as the browser encounters it.
Runs the function immediately without calling it
Typically used in
Shortcut of Declaring a Function Expression
Arrow function expressions - JavaScript | MDN (mozilla.org)
Remember, we're saying "SHORTCUT" of Function Expression
Meaning anything that's on arrow function will not be HOISTED
PROBLEM: this
keyword of a function inside of a function
Earlier, we saw that this
keyword used when we created an object constructor
and you may remember, this
keyword can be used inside any object to refer back to the object itself. So what's happening here is this function is hoisted out of the object and up to the global scope.
SOLUTION: Arrow function
An arrow function does not have its own this
It does not know what this
means
--> and it will refer to the closest available scope which in this case is the object.
This also explains why we can't use an arrow function as the declaration for a method,
because if we did that, the arrow function wouldn't know what scope to use.
So it would refer back to the global scope
instead of the method scope
and therefore nothing would work properly inside that arrow function.
In JavaScript,
a callback is a function that is passed as an argument to another function
is executed after the completion of some asynchronous operation or event.
Basically we are ==using functions as a parameter to a function
A callback is a function used as a parameter in a function
function fetchData(callback) {
// Simulating an asynchronous operation
setTimeout(() => {
const data = { name: "Alice", age: 30 };
callback(data); // The callback function is called with the fetched data
}, 1000); // Simulating a delay of 1 second
}
// Using the fetchData function with a callback
fetchData(
(result) => {
console.log("Data received:", result);
}
)
// ^-- The argument here is an anonymous arrow function
Notes:
Callbacks are used to manage the flow of control in scenarios where operations may take some time to complete, such as:
A single line way of writing if else
statements
for (let i = 0; i < length; i++) {
// code here
}
for of
for (const item of items) {
// code here
}
array.forEach(arg: anon-arrow-function)
items.forEach(
(item) => {
// code here
}
)
for in
for (const singleObject in nestedObjects) {
// code here
}
const stuffItems = items.map(
(item) => {
// code here
return item
}
)
UPDATE: The event listener chapter isn't that good. I'd have to rely on other resources.
Everything that happens in the browser is an event.
Fuck this is confusing, I'll probably learn this a long the way
const btn = document.querySelector("button");
const lidToggle = (arg1) => {
return arg1;
}
btn.addEventListener("click", lidToggle)
undefined
means there's no value in it but it's taking up space in the memory.
Remember that when you create a variable, you're creating a space in the memory.
Think of it like putting a box, that box is a variable, inside of that box will be a value
When it's undefined
, the box is empty.
Like pointers
but in javascript
let newDeskArr = [...deskArray];
The original array is deskArray
,
now whatever we change to newDeskArr
will also affect the original array
It's called "shallow copy"
With array.splice()
. Provided you have the index
You can:
array.splice(indexReplaced, 1, NewValue)
// Index#, replace 1 element with this, new value"array.splice(indexRemoved, 1)
// Index#, remove 1 element array.splice(indexAdd, 0, AddedVal)
// Index#, remove none, add the new value What is the difference between the array.forEach() and array.map() methods?
array.forEach() executes a provided callback function once for each item in the array. array.map() creates a new array with the results of executing a provided callback function once for each item in the original array.
True or false: An arrow function can be used to define an object method.
FALSE
The key to all of that was realizing, in JavaScript, everything is an object. Those objects have properties, and those objects have methods that act on those properties. And that's the lesson I've tried to share with
Questions: What is ECMAScript?
The specification describing how browsers should implement and interpret JavaScript.
An event listener can be appended to the window object.
How do you capture the event object in an event listener?
Answer: The event object is automatically passed as a parameter to the callback function. Simply name and use the parameter.